package com.carsa.blackberry.domain.services.impl;

import java.io.IOException;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.carsa.blackberry.CarsaApp;
import com.carsa.blackberry.Dummy;
import com.carsa.blackberry.MainKeys;
import com.carsa.blackberry.domain.dto.ArticuloDTO;
import com.carsa.blackberry.domain.dto.DriverDTO;
import com.carsa.blackberry.domain.dto.DriversQueueDTO;
import com.carsa.blackberry.domain.dto.EntregaDTO;
import com.carsa.blackberry.domain.dto.EntregasQueueDTO;
import com.carsa.blackberry.domain.dto.QueueMessageDTO;
import com.carsa.blackberry.domain.dto.ReasonDTO;
import com.carsa.blackberry.domain.dto.ReasonsQueueDTO;
import com.carsa.blackberry.domain.dto.SecondReasonDTO;
import com.carsa.blackberry.domain.services.GenericService;
import com.carsa.blackberry.domain.services.webServices.WebServiceManager;
import com.carsa.blackberry.domain.services.webServices.ZSdareLegajos_Service;
import com.carsa.blackberry.domain.services.webServices.ZSdareMotivos_Service;
import com.carsa.blackberry.domain.services.webServices.impl.ZSdareLegajos.ZSdareLegajo;
import com.carsa.blackberry.domain.services.webServices.impl.ZSdareLegajos.ZsdareLegajost;
import com.carsa.blackberry.domain.services.webServices.impl.ZSdareMotivos.ZSdareMotivo;
import com.carsa.blackberry.domain.services.webServices.impl.ZSdareMotivos.ZsdareMotivost;
import com.carsa.blackberry.util.DateUtil;
import com.carsa.blackberry.util.Logger;
import com.carsa.blackberry.util.Util;
import com.carsa.blackberry.util.persistence.FileHandler;
import com.carsa.blackberry.util.persistence.FileHandlerImpl;
import com.carsa.blackberry.util.persistence.Persistable;

/**
 * @author Nahuel Barrios.
 * @since 23/08/2010.
 * @version 1.0
 */
public class GenericServiceImpl implements GenericService {

    WebServiceManager _wsManager = new WebServiceManager();

    /**
     * Exporta la cola aNewQueue al archivo de persistencia de mensajes.
     * 
     * @param anObject
     *            La nueva cola de mensajes.
     */
    public void exportObjectToPersistenceFile(Persistable anObject) {

	FileHandler fHandler = new FileHandlerImpl();
	fHandler.entablishConnection(anObject.getPersistPath());

	if (!fHandler.overwriteWith(anObject.getStringToPersist()))
	    Logger.logError("No se pudo persistir el objeto, se perderan los cambios. El objeto era: \n"
		    + anObject.toString());
    }

    public DriverDTO validateLegajoAyudante(String legajo) {
	DriversQueueDTO legajos = (DriversQueueDTO) CarsaApp.getMemory().get(MainKeys.PARAMETER_LEGAJOS);

	String tmp= legajo;
	Enumeration ayudantes = legajos.getOnlyAyudantes().elements();
	while (ayudantes.hasMoreElements()) {
	    DriverDTO unLegajo = (DriverDTO) ayudantes.nextElement();
	    
	    DriverDTO ret = null;
	    for (int count = 0; count <= 5; count++) {
		if (unLegajo.getLegajo().equals(tmp))
		    ret = unLegajo;

		if (ret != null)
		    return ret;

		tmp = "0" + tmp;
	    }
	    
	    tmp= legajo;
	}

	return null;
    }

    /**
     * @param unaEntrega
     */
    // TODO : Javadoc : Terminate this Javadoc.
    public void refreshPersistenceFile(EntregaDTO unaEntrega) {
	Vector entregas = new Vector();
	entregas.addElement(unaEntrega);
	this.refreshPersistenceFile(entregas);
    }

    /**
     * @param entregasVector
     */
    // TODO : Javadoc : Terminate this Javadoc.
    private void refreshPersistenceFile(Vector entregasVector) {
	EntregasQueueDTO pendingEntregas = (EntregasQueueDTO) CarsaApp.getMemory()
	        .get(MainKeys.PARAMETER_PENDING_QUEUE);

	String legajo = (String) CarsaApp.getMemory().get(MainKeys.PARAMETER_LEGAJO_DRIVER);

	Enumeration elements = entregasVector.elements();
	while (elements.hasMoreElements()) {
	    EntregaDTO unaEntrega = (EntregaDTO) elements.nextElement();

	    Vector lasPendientes = pendingEntregas.getEntregas(legajo);
	    Enumeration entregas = lasPendientes.elements();
	    while (entregas.hasMoreElements()) {
		EntregaDTO eachEntrega = (EntregaDTO) entregas.nextElement();

		if (eachEntrega.getVbeln().equals(unaEntrega.getVbeln())) {
		    lasPendientes.removeElement(eachEntrega);
		    lasPendientes.addElement(unaEntrega);
		}

	    }// TODO : Functionality : hacer mejor esto.
	}

	this.exportObjectToPersistenceFile(pendingEntregas);
    }

    /**
     * @param legajos
     *            Un {@link Vector} de {@link ZSdareLegajo} conteniendo los legajos recuperados por el WS.
     * @return Un nuevo {@link Vector} conteniendo un listado de {@link DriverDTO}.
     */
    public Vector parseLegajos(Vector legajos) {
	Vector ret = new Vector();

	Enumeration elements = legajos.elements();
	while (elements.hasMoreElements()) {
	    ZSdareLegajo unLegajo = (ZSdareLegajo) elements.nextElement();
	    ret.addElement(new DriverDTO(unLegajo.getName1(), unLegajo.getLegaj(), unLegajo.getPuest(), unLegajo.getWerks()));
	}

	return ret;
    }



    public DriversQueueDTO fetchLegajos() {
	DriversQueueDTO driversQueue = new DriversQueueDTO();

	FileHandler fHandler = new FileHandlerImpl();
	fHandler.entablishConnection(driversQueue.getPersistPath());
	String fileData = null;
	try {
	    fileData = fHandler.getFileData();
	}
	catch (IOException e) {
	    Logger.logError(Logger.getLocationMessageFor(this, "fetchLegajos()"), e);
	}
	Logger.logInfo("fileData: " + fileData);

	boolean haveToCallWebService = true;
	if (fileData != null && !fileData.equals("")) {
	    driversQueue = new DriversQueueDTO(fileData);
	    Logger.logInfo("lastUpdate: " + driversQueue.getLastUpdate());

	    if (DateUtil.daysBetween(driversQueue.getLastUpdate(), Calendar.getInstance().getTime()) > MainKeys.NUMBER_OF_DAYS_BETWEEN_FILES_UPDATE)
		haveToCallWebService = true;
	}

	// Si ya pasaron mas de X dias desde la ultima actualizacion, entonces tengo que actualizar el listado de
	// choferes
	if (haveToCallWebService) {
	    ZsdareLegajost response = (ZsdareLegajost) _wsManager.call(new ZSdareLegajos_Service());

	    // Una vez actualizados los choferes, vuelvo a persistir el XML.
	    if (response != null) {
		driversQueue.setDrivers(this.parseLegajos(Util.getVectorFrom(response.getItem())));
		driversQueue.setLastUpdate(Calendar.getInstance().getTime());

		this.exportObjectToPersistenceFile(driversQueue);
	    }
	}

	return driversQueue;
    }

    public Hashtable fetchMotivos() {
	ReasonsQueueDTO reasonsQueue = new ReasonsQueueDTO();

	FileHandler fHandler = new FileHandlerImpl();
	fHandler.entablishConnection(reasonsQueue.getPersistPath());
	String fileData = null;
	try {
	    fileData = fHandler.getFileData();
	}
	catch (IOException e) {
	    Logger.logError(Logger.getLocationMessageFor(this, "fetchDriversFromWS()"), e);
	}
	Logger.logInfo("fileData: " + fileData);

	boolean haveToCallWebService = true;
	if (fileData != null && !fileData.equals("")) {
	    reasonsQueue = new ReasonsQueueDTO(fileData);
	    Logger.logInfo("lastUpdate: " + reasonsQueue.getLastUpdate());

	    if (DateUtil.daysBetween(reasonsQueue.getLastUpdate(), Calendar.getInstance().getTime()) > MainKeys.NUMBER_OF_DAYS_BETWEEN_FILES_UPDATE)
		haveToCallWebService = true;
	}

	// Si ya pasaron mas de X dias desde la ultima actualizacion, entonces tengo que actualizar el listado de
	// choferes
	if (haveToCallWebService) {
//	    ZsdareMotivost response = (ZsdareMotivost) _wsManager.call(new ZSdareMotivos_Service());// TODO : Dummy : Motivos.
	    ZsdareMotivost response = Dummy.getMotivos();// TODO : Dummy : Motivos.

	    // Una vez actualizados los choferes, vuelvo a persistir el XML.
	    if (response != null) {
		reasonsQueue.setReasons(this.parseMotivos(Util.getVectorFrom(response.getItem())));
		reasonsQueue.setLastUpdate(Calendar.getInstance().getTime());

		this.exportObjectToPersistenceFile(reasonsQueue);
	    }
	}

	return reasonsQueue.getReasons();
    }

    /**
     * @param motivos
     * @return
     */
    // TODO : Javadoc : Terminate this Javadoc.
    private Hashtable parseMotivos(Vector motivos) {
	Hashtable ret = new Hashtable();

	Enumeration elements = motivos.elements();
	while (elements.hasMoreElements()) {
	    ZSdareMotivo unMotivo = (ZSdareMotivo) elements.nextElement();

	    Enumeration retElements = ret.elements();
	    boolean flag = true;
	    while (retElements.hasMoreElements()) {
		ReasonDTO aReason = (ReasonDTO) retElements.nextElement();
		if (flag && aReason.getReasonCode().equals(unMotivo.getGrund())) {
		    aReason.addSecondReason(new SecondReasonDTO(unMotivo.getDdtxt(), unMotivo.getSubmo(), unMotivo
			    .getFlepa(), unMotivo.getGrund()));
		    flag = false;
		}
	    }

	    if (flag) {
		ReasonDTO reason = new ReasonDTO();
		reason.setReasonCode(unMotivo.getGrund());
		reason.setReasonDescript(unMotivo.getGtext());
		reason.addSecondReason(new SecondReasonDTO(unMotivo.getDdtxt(), unMotivo.getSubmo(), unMotivo
		        .getFlepa(), unMotivo.getGrund()));
		ret.put(reason.getReasonCode(), reason);
	    }

	}

	return ret;
    }

    public Object[] getReasonsAndSubreasons() {
	Object[] ret = new Object[2];

	Vector reasons = new Vector();
	Vector subReasons = new Vector();

	Vector reasonsAndSubreasons = (Vector) CarsaApp.getMemory().get(MainKeys.PARAMETER_REASONS_AND_SUBREASONS);

	Enumeration elements = reasonsAndSubreasons.elements();
	while (elements.hasMoreElements()) {
	    ReasonDTO aReason = (ReasonDTO) elements.nextElement();
	    reasons.addElement(aReason.getReasonDescript());
	    // subReasons.addElement(aReason.getSecondReasonDescript());
	}

	ret[0] = reasons;
	ret[1] = subReasons;

	return ret;
    }

    /**
     * @param reasonsDescript
     * @return
     */
    // TODO : Javadoc : Terminate this Javadoc.
    public Vector doMappingWithReasons(Vector reasonsDescript) {
	Vector ret = new Vector();

	Vector reasons = (Vector) CarsaApp.getMemory().get(MainKeys.PARAMETER_REASONS_AND_SUBREASONS);

	Enumeration descripts = reasonsDescript.elements();
	while (descripts.hasMoreElements()) {
	    String aDescript = (String) descripts.nextElement();

	    Enumeration reasonsElements = reasons.elements();
	    while (reasonsElements.hasMoreElements()) {
		ReasonDTO aReason = (ReasonDTO) reasonsElements.nextElement();

		if (aReason.getReasonDescript().equals(aDescript))
		    ret.addElement(aReason.getReasonCode());
	    }
	}

	return ret;
    }

    /**
     * @param subreasonsDescript
     * @return
     */
    // TODO : Javadoc : Terminate this Javadoc.
    public Vector doMappingWithSubreasons(Vector subreasonsDescript) {
	Vector ret = new Vector();

	Hashtable reasons = (Hashtable) CarsaApp.getMemory().get(MainKeys.PARAMETER_REASONS_AND_SUBREASONS);

	Enumeration descripts = subreasonsDescript.elements();
	while (descripts.hasMoreElements()) {
	    String aDescript = (String) descripts.nextElement();

	    Enumeration reasonsElements = reasons.elements();
	    while (reasonsElements.hasMoreElements()) {
		ReasonDTO aReason = (ReasonDTO) reasonsElements.nextElement();

		boolean flag = true;
		Enumeration subreasonsElements = aReason.getSubreasons().elements();
		while (subreasonsElements.hasMoreElements()) {
		    SecondReasonDTO secondReason = (SecondReasonDTO) subreasonsElements.nextElement();

		    if (flag && secondReason.getDescript().equals(aDescript)) {
			ret.addElement(secondReason.getCode());
			flag = false;
		    }
		}
	    }
	}

	return ret;
    }





    public void pushMessageIntoQueue(ArticuloDTO anArticle) {
	QueueMessageDTO aMessage = new QueueMessageDTO();
	aMessage.setParameters(anArticle.toXMLString());
	aMessage.setWebServiceName(MainKeys.WS_NAME_ZSDARE_ARE);
	aMessage.setWebServiceMethod(MainKeys.WS_NAME_ZSDARE_ARE);

	CarsaApp.getPersistenceThread().pushMessageIntoQueue(aMessage);
    }

    public void pushEntregaInHistory(EntregaDTO unaEntrega) {
	EntregasQueueDTO queue= (EntregasQueueDTO)CarsaApp.getMemory().get(MainKeys.PARAMETER_ENTREGAS_HISTORY);
	
	queue.add(unaEntrega, (String)CarsaApp.getMemory().get(MainKeys.PARAMETER_LEGAJO_DRIVER));
	
	this.exportObjectToPersistenceFile(queue);
    }

  








}
